home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Texteditors
/
Mg1b
/
Source
/
amiga
/
ttykbd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-26
|
12KB
|
433 lines
/*
* Name: MicroEMACS
* Amiga virtual terminal keyboard, default console keymap.
* Version: Gnu v30
* Last edit: 25-Oct-86
* Created: 19-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
* This goes with the Intuition terminal driver,
* and implements Mike Meyer's hot mouse.
*/
#include <exec/types.h>
#include <intuition/intuition.h>
#undef TRUE
#undef FALSE
#include "def.h"
#define ESC 0x1B /* Escape, arrows et al. */
#define CSI 0x9B /* Amiga CSI */
#ifdef MOUSE
/* Stuff for the hot mouse. Since right now the mouse
* keys get bound into a wierd place, a lot of the
* jiggery-pokery up here is to make it possible
* to shift their location in the keymap without too
* much fuss. Sorry for the horrid macro names...
*/
/* key code w/o mini qualifiers */
#define WMOUSE ((KEY)(KCTRL | KMETA | 'a'))
#define SMOUSE ((KEY)(KCTRL | KMETA | 'i'))
#define EMOUSE ((KEY)(KCTRL | KMETA | 'q'))
/* mini qualifiers */
#define SHFT 1
#define ALT 2
#define CTRL 4
/* macros to create qualified key codes */
#define S(k) (k + SHFT)
#define A(k) (k + ALT)
#define C(k) (k + CTRL)
#define AS(k) (k + SHFT + ALT)
#define CS(k) (k + CTRL + SHFT)
#define CA(k) (k + CTRL + ALT)
#define CAS(k) (k + SHFT + ALT + CTRL)
#endif /* ifdef MOUSE */
#ifdef XKEYS
/*
* The function keys on the Amiga send back
* escape sequences of the form <ESC>[code~, where code
* is a one or two-character code for the key. To make
* it easier to decode, we place the internal key values
* for these codes in this table.
*/
short consolemap[] = {
KF1, KF2, KF3, KF4,
KF5, KF6, KF7, KF8,
KF9, KF10, KSF1, KSF2,
KSF3, KSF4, KSF5, KSF6,
KSF7, KSF8, KSF9, KSF10
};
#define NFUNCKEYS ((sizeof consolemap)/(sizeof consolemap[0]))
#endif
/*
* Names for the keys with basic keycode
* between KFIRST and KLAST (inclusive). This is used by
* the key name routine in "kbd.c". KFIRST is KRANDOM,
* which we don't bind anything useful to. "The Menu" is
* special; we implement menus as another function key,
* but there isn't really any "MENU" key on the keyboard.
* There is no shifted value for the help key. Mouse clicks
* have been moved to a hitherto unused part of the keymap.
*/
#ifdef DO_MENU
#define MENUNAME "The Menu"
#else
#define MENUNAME NULL
#endif
char *keystrings[] = {
#ifdef XKEYS
NULL, "F1", "F2", "F3",
"F4", "F5", "F6", "F7",
"F8", "F9", "F10", "Shift-F1",
"Shift-F2", "Shift-F3", "Shift-F4", "Shift-F5",
"Shift-F6", "Shift-F7", "Shift-F8", "Shift-F9",
"Shift-F10", "Up", "Shift-Up", "Down",
"Shift-Down", "Left", "Shift-Left", "Right",
"Shift-Right", "Help", MENUNAME, NULL
#else
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, MENUNAME, NULL
#endif
};
/*
* Read in a key, doing the low level mapping
* of ASCII code to 11 bit code. This level deals with
* mapping the special keys into their spots in the C1
* control area. The C0 controls go right through, and
* get remapped by "getkey". Returning function keys
* with KMETA set distinguishes these keys from codes
* generated by ALT-ing a control key (which I want
* to have mapped in the usual way).
*/
getkbd()
{
register int c;
#ifdef XKEYS
register int n;
#endif
loop:
c = ttgetc();
if (c == CSI) {
c = ttgetc();
#ifdef MOUSE
if (c == 'P') { /* mouse sequence */
ttgetc(); /* discard '~' */
return (KCTRL | getmouse()); /* create key code */
}
#endif
#ifdef DO_MENU
if (c == 'M') { /* (fake) menu key */
ttgetc(); /* discard '~' */
return (KCTRL | KMENU);
}
#endif
#ifdef XKEYS
if (c == '?') { /* HELP key */
ttgetc(); /* discard '~' */
return (KCTRL | KHELP);
}
/* Arrow keys */
if (c == 'A')
return (KCTRL | KUP);
if (c == 'B')
return (KCTRL | KDOWN);
if (c == 'C')
return (KCTRL | KRIGHT);
if (c == 'D')
return (KCTRL | KLEFT);
if (c == 'T')
return (KCTRL | KSUP);
if (c == 'S')
return (KCTRL | KSDOWN);
/* Shifted left, right arrow */
if (c == ' ') {
c = ttgetc();
if (c == 'A' || c == '@')
return (KCTRL | ((c == 'A') ?
(KSLEFT) : (KSRIGHT)));
goto loop; /* try again, sucker */
}
/* Function keys */
if (c >= '0' && c <= '9') {
n = 0;
do {
n = 10*n + c - '0';
c = ttgetc();
} while (c>='0' && c<='9');
if (c == '~' && n < NFUNCKEYS) {
c = consolemap[n];
if (c != KRANDOM)
return (KCTRL | c);
goto loop;
}
else
goto loop; /* Try again */
}
#endif
goto loop; /* Try again */
}
return (c);
}
#ifdef MOUSE
/*
* A hack for the hot mouse -- peek ahead at the
* next mouse event and construct an internal key
* code. Might as well use those extra binding slots...
*/
getmouse()
{
USHORT row, col, qual;
int ttmouse();
register int code = 0;
register struct WINDOW *wp;
ttmouse(FALSE, &row, &col, &qual); /* look at mouse */
/* was the click in a window ??? */
for (wp = wheadp; wp != NULL; wp = wp->w_wndp)
if ((row >= wp->w_toprow) &&
(row <= (wp->w_toprow + wp->w_ntrows)))
break ;
/* figure out what area the click was in */
if (wp == NULL) /* not found; assume echo line */
code = EMOUSE;
else if (row == (wp->w_toprow + wp->w_ntrows)) /* status line */
code = SMOUSE;
else
code = WMOUSE; /* click in a window */
/* figure out 'mini' qualifiers -- ADD them, because 'a' isn't */
/* divisible by 2... This took me 2 hours to realize... */
if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
code += SHFT;
if (qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
code += ALT;
if (qual & IEQUALIFIER_CONTROL)
code += CTRL;
return (code);
}
#endif
/*
* Terminal specific keymap initialization.
*
* Bind all of the assigned graphics in the
* Amiga alternate character set to self-insert.
*
* #ifdef XKEYS, attach the special keys to the appropriate
* built-in functions.
*
* #ifdef DO_MENU, bind the fake KMENU code to amigamenu()
* to do menu selection as transparently as possible.
*
* #ifdef MOUSE, bind the hot mouse keys to the
* functions. In the case of window and mode line
* selections, call special functions
* special functions that select the appropriate
* object (i.e. character, window) before performing
* the task.
*
* As is the case of all the keymap routines, errors
* result in panic.
*/
extern int togglewindow(); /* Defined by "ttyio.c" */
#ifdef DO_MENU
extern int amigamenu(); /* Defined by "ttymenu.c" */
#endif
#ifdef CHANGE_FONT
extern int setfont(); /* Defined by "ttyio.c" */
#endif
#ifdef MOUSE
extern int amigamouse(); /* Defined by "ttymouse.c" */
extern int mreposition(); /* Functions which select the */
extern int mdelfword(); /* window the click was in, */
extern int mkillline(); /* then call another one */
extern int mforwdel(); /* Defined in "ttymouse.c" */
extern int mdelwhite();
extern int mkillregion();
extern int myank();
extern int mforwpage();
extern int mbackpage();
extern int msplitwind();
extern int mdelwind();
extern int mgotobob();
extern int mgotoeob();
extern int menlargewind();
extern int mshrinkwind();
#endif
#ifdef CHANGE_COLOR
/* functions to mess with the mode line rendition, window colors*/
extern int ttmode(); /* Defined by "tty.c" */
extern int tttext(); /* "" */
extern int textforeground(); /* "" */
extern int textbackground(); /* "" */
extern int modeforeground(); /* "" */
extern int modebackground(); /* "" */
#endif
VOID
ttykeymapinit()
{
register SYMBOL *sp;
register int i;
/* Intuition window manipulation */
#ifndef MEYN
keydup((KEY)KMETA|KCTRL|'L', "redraw-display");
#endif
keyadd((KEY)-1, togglewindow, "toggle-window-hack");
/*
* Bind all positions that correspond
* to characters in the Amiga alternate
* character set to "ins-self". These characters may
* be used just like any other character. Of course,
* if DO_METAKEY is defined in kbd.c, the alternate character
* set will get mapped to META-ed keys...
*/
if ((sp=symlookup("self-insert-command")) == NULL)
panic("ttykeymapinit: can't find self-insert-command");
for (i=0xA0; i<0xFF; ++i) {
if (binding[i] != NULL)
panic("ttykeymapinit: key already bound");
binding[i] = sp;
}
#ifdef DO_MENU
/* "Menu" key, if compiled in */
keyadd((KEY)KMENU, amigamenu, "amiga-menu");
#endif
#ifdef CHANGE_FONT
keyadd((KEY)-1, setfont, "set-font");
#endif
#ifdef CHANGE_COLOR
/* Functions to allow you to change colors */
keyadd((KEY)-1, ttmode, "set-mode-rendition");
keyadd((KEY)-1, tttext, "set-text-rendition");
keyadd((KEY)-1, textforeground, "set-text-foreground");
keyadd((KEY)-1, textbackground, "set-text-background");
keyadd((KEY)-1, modeforeground, "set-mode-foreground");
keyadd((KEY)-1, modebackground, "set-mode-background");
#endif
#ifdef XKEYS
/* Arrow keys */
keydup((KEY)KUP, "previous-line");
keydup((KEY)KDOWN, "next-line");
keydup((KEY)KSUP, "backward-paragraph");
keydup((KEY)KSDOWN, "forward-paragraph");
keydup((KEY)KRIGHT, "forward-char");
keydup((KEY)KLEFT, "backward-char");
keydup((KEY)KSRIGHT, "forward-word");
keydup((KEY)KSLEFT, "backward-word");
/* Function keys */
keydup((KEY)KHELP, "describe-key-briefly");
keydup((KEY)KF1, "find-file");
keydup((KEY)KSF1, "find-file-other-window");
keydup((KEY)KF2, "save-buffer");
keydup((KEY)KSF2, "write-file");
keydup((KEY)KF3, "scroll-up");
keydup((KEY)KSF3, "scroll-down");
keydup((KEY)KF4, "next-window");
keydup((KEY)KSF4, "previous-window");
keydup((KEY)KF5, "enlarge-window");
keydup((KEY)KSF5, "shrink-window");
keydup((KEY)KF6, "fill-paragraph");
keydup((KEY)KSF6, "query-replace");
keydup((KEY)KF7, "split-window-vertically");
keydup((KEY)KSF7, "delete-other-windows");
keydup((KEY)KF8, "global-set-key");
keydup((KEY)KSF8, "global-unset-key");
keydup((KEY)KF9, "start-kbd-macro");
keydup((KEY)KSF9, "end-kbd-macro");
keydup((KEY)KF10, "call-last-kbd-macro");
keydup((KEY)KSF10, "save-buffers-kill-emacs");
#endif
#ifdef MOUSE
/* Mouse clicks in a window do editing functions on the */
/* window. */
keyadd(WMOUSE, amigamouse, "amiga-mouse");
keyadd(S(WMOUSE), mreposition, "mouse-recenter");
keyadd(A(WMOUSE), mdelfword, "mouse-kill-word");
keyadd(AS(WMOUSE), mkillline, "mouse-kill-line");
keyadd(C(WMOUSE), mforwdel, "mouse-delete-char");
keyadd(CS(WMOUSE), mdelwhite, "mouse-just-one-space");
keyadd(CA(WMOUSE), mkillregion, "mouse-kill-region");
keyadd(CAS(WMOUSE), myank, "mouse-yank");
/* Mouse clicks in the status line select that window and */
/* then perform a command on that window or buffer. */
/* Use keyadd() because they haven't been bound before */
keyadd(SMOUSE, mforwpage, "mouse-scroll-up");
keyadd(S(SMOUSE), mbackpage, "mouse-scroll-down");
keyadd(A(SMOUSE), msplitwind, "mouse-split-window-vertically");
keyadd(AS(SMOUSE), mdelwind, "mouse-delete-window");
keyadd(C(SMOUSE), mgotobob, "mouse-beginning-of-buffer");
keyadd(CS(SMOUSE), mgotoeob, "mouse-end-of-buffer");
keyadd(CA(SMOUSE), menlargewind,"mouse-enlarge-window");
keyadd(CAS(SMOUSE),mshrinkwind, "mouse-shrink-window");
/* mouse clicks in echo line do global things */
#ifdef MEYN
keydup(EMOUSE, "save-buffer");
#else
keydup(EMOUSE, "switch-to-buffer");
#endif
keydup(S(EMOUSE), "kill-buffer");
keydup(A(EMOUSE), "describe-key-briefly");
keydup(AS(EMOUSE), "describe-bindings");
keydup(C(EMOUSE), "suspend-emacs");
keydup(CS(EMOUSE), "save-buffers-kill-emacs");
keydup(CA(EMOUSE), "list-buffers");
keydup(CAS(EMOUSE), "toggle-window-hack");
#endif
}